package org.javaqq.face.main.gui;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;

import org.javaqq.face.main.tree.ContactNode;
import org.javaqq.face.util.AntialiasingManager;
import org.javaqq.face.util.BufferedImageConverter;

import sun.swing.DefaultLookup;

public class TableListCellRenderer extends JPanel implements TableCellRenderer,
		Icon {

	JLabel imageLabel = new JLabel();

	private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1,
			1);
	private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1,
			1, 1);
	protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;

	private JTable table;

	private boolean isSelected, hasFocus;

	private int row, column;

	private Object value;

	private Color unselectedForeground;
	private Color unselectedBackground;

	public TableListCellRenderer() {
		super();
		this.setLayout(new FlowLayout(FlowLayout.CENTER));
		this.setOpaque(true);
		setBorder(getNoFocusBorder());
		imageLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
		this.add(imageLabel);
	}

	private Border getNoFocusBorder() {
		Border border = DefaultLookup.getBorder(this, ui,
				"Table.cellNoFocusBorder");
		if (System.getSecurityManager() != null) {
			if (border != null)
				return border;
			return SAFE_NO_FOCUS_BORDER;
		} else if (border != null) {
			if (noFocusBorder == null
					|| noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {
				return border;
			}
		}
		return noFocusBorder;
	}

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {

		this.table = table;
		this.isSelected = isSelected;
		this.hasFocus = hasFocus;
		this.row = row;
		this.column = column;
		this.value = value;
		Color fg = null;
		Color bg = null;
		imageLabel.setIcon(null);

		JTable.DropLocation dropLocation = table.getDropLocation();
		if (dropLocation != null && !dropLocation.isInsertRow()
				&& !dropLocation.isInsertColumn()
				&& dropLocation.getRow() == row
				&& dropLocation.getColumn() == column) {

			fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
			bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");

			isSelected = true;
		}

		if (isSelected) {
			super.setForeground(fg == null ? table.getSelectionForeground()
					: fg);
			super.setBackground(bg == null ? table.getSelectionBackground()
					: bg);
		} else {
			Color background = unselectedBackground != null ? unselectedBackground
					: table.getBackground();
			if (background == null
					|| background instanceof javax.swing.plaf.UIResource) {
				Color alternateColor = DefaultLookup.getColor(this, ui,
						"Table.alternateRowColor");
				if (alternateColor != null && row % 2 == 0)
					background = alternateColor;
			}
			super
					.setForeground(unselectedForeground != null ? unselectedForeground
							: table.getForeground());
			super.setBackground(background);
		}

		setFont(table.getFont());

		if (hasFocus) {
			Border border = null;
			if (isSelected) {
				border = DefaultLookup.getBorder(this, ui,
						"Table.focusSelectedCellHighlightBorder");
			}
			if (border == null) {
				border = DefaultLookup.getBorder(this, ui,
						"Table.focusCellHighlightBorder");
			}
			setBorder(border);

			if (!isSelected && table.isCellEditable(row, column)) {
				Color col;
				col = DefaultLookup.getColor(this, ui,
						"Table.focusCellForeground");
				if (col != null) {
					super.setForeground(col);
				}
				col = DefaultLookup.getColor(this, ui,
						"Table.focusCellBackground");
				if (col != null) {
					super.setBackground(col);
				}
			}
		} else {
			setBorder(getNoFocusBorder());
		}

		if (value instanceof ContactNode) {
			ContactNode contactNode = (ContactNode) value;
			String name = contactNode.getContact().getNickName();
			BufferedImage image = contactNode.getImage();
			if (name != null) {
				imageLabel.setText(name);
			}
			if (image != null) {
				image = BufferedImageConverter.getFasterScaledInstance(image,
						20, 20, RenderingHints.VALUE_INTERPOLATION_BILINEAR,
						false);
				// statusLabel.setIcon(new ImageIcon(image));
				imageLabel.setIcon(new ImageIcon(image));
			}

		} else if (value instanceof String) {
			String name = (String) value;
			imageLabel.setText(name);
		}
		imageLabel.doLayout();
		this.doLayout();
		this.repaint();
		this.validate();
		return this;
	}

	/**
	 * Overrides <code>JComponent.setForeground</code> to assign the
	 * unselected-foreground color to the specified color.
	 * 
	 * @param c
	 *            set the foreground color to this value
	 */
	public void setForeground(Color c) {
		super.setForeground(c);
		unselectedForeground = c;
	}

	/**
	 * Overrides <code>JComponent.setBackground</code> to assign the
	 * unselected-background color to the specified color.
	 * 
	 * @param c
	 *            set the background color to this value
	 */
	public void setBackground(Color c) {
		super.setBackground(c);
		unselectedBackground = c;
	}

	public void updateUI() {
		super.updateUI();
		setForeground(null);
		setBackground(null);
	}

	public boolean isOpaque() {
		Color back = getBackground();
		Component p = getParent();
		if (p != null) {
			p = p.getParent();
		}

		// p should now be the JTable.
		boolean colorMatch = (back != null) && (p != null)
				&& back.equals(p.getBackground()) && p.isOpaque();
		return !colorMatch && super.isOpaque();
	}

	@Override
	public int getIconHeight() {
		return this.getHeight() + 10;
	}

	@Override
	public int getIconWidth() {
		return this.getWidth() + 10;
	}

	@Override
	public void paintIcon(Component c, Graphics g, int x, int y) {

		Graphics2D g2 = (Graphics2D) g.create();
		try {
			AntialiasingManager.activateAntialiasing(g2);

			g2.setColor(Color.WHITE);
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
					0.8f));
			g2.fillRoundRect(x, y, getIconWidth() - 1, getIconHeight() - 1, 10,
					10);
			g2.setColor(Color.DARK_GRAY);
			g2.drawRoundRect(x, y, getIconWidth() - 1, getIconHeight() - 1, 10,
					10);

			// Indent component content from the border.
			g2.translate(x + 5, y + 5);

			// Paint component.
			super.paint(g2);

			//
			g2.translate(x, y);
		} finally {
			g.dispose();
		}

	}

	/*
	 * private void internalPaintComponent(Graphics g) { if(!(value instanceof
	 * ContactNode) && !isSelected){ return; } System.out.println(isSelected);
	 * Graphics2D g2 = (Graphics2D) g; if (!isSelected) {
	 * 
	 * //super.setForeground(table.getSelectionForeground());
	 * this.setBackground(table.getSelectionBackground()); g2.fillRect(0, 0,
	 * getWidth(), getHeight()); }else{ this.setBackground(Color.WHITE);
	 * g2.fillRect(0, 0, getWidth(), getHeight()); }
	 * 
	 * }
	 * 
	 * protected void paintComponent(Graphics g) { super.paintComponent(g);
	 * 
	 * g = g.create(); try { internalPaintComponent(g); } finally { g.dispose();
	 * } }
	 */

}
